{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Pandas 修改数据值\n\n本教程详细介绍如何在 Pandas DataFrame 中修改数据值的各种方法。\n\n## 目录\n1. 直接赋值修改\n2. 使用 loc 和 iloc 修改\n3. 使用 at 和 iat 修改单个值\n4. 使用 replace() 替换值\n5. 使用 apply() 和 map() 修改\n6. 使用 where() 和 mask() 条件修改\n7. 批量修改和转换"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 导入库"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import pandas as pd\nimport numpy as np"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 1. 直接赋值修改\n\n### 方法说明\n\n最简单的方法是直接给列赋值。\n\n**语法:**\n```python\ndf['列名'] = 新值\n```\n\n**特点:**\n- ✅ 简单直观\n- ✅ 直接修改原 DataFrame\n- ✅ 支持常量、列表、Series、计算结果\n\n**适用场景:** 修改整列数据"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 示例1: 创建示例数据"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "df = pd.DataFrame({\n    '姓名': ['张三', '李四', '王五'],\n    '年龄': [25, 30, 35],\n    '城市': ['北京', '上海', '广州']\n})\n\nprint(\"原始 DataFrame:\")\nprint(df)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 示例2: 修改整列（基于计算）\n\n所有年龄加 1。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "df_copy = df.copy()\ndf_copy['年龄'] = df_copy['年龄'] + 1\nprint(\"所有年龄加1:\")\nprint(df_copy)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 示例3: 修改整列为常量\n\n将所有城市改为深圳。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "df_copy = df.copy()\ndf_copy['城市'] = '深圳'\nprint(\"所有城市改为深圳:\")\nprint(df_copy)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 示例4: 基于条件修改\n\n使用 `loc` 进行条件修改。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "df_copy = df.copy()\ndf_copy.loc[df_copy['年龄'] > 30, '年龄'] = 30\nprint(\"年龄大于30的改为30:\")\nprint(df_copy)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 2. 使用 loc 和 iloc 修改\n\n### 方法说明\n\n`loc` 和 `iloc` 是最常用的修改方法。\n\n**语法:**\n```python\ndf.loc[行标签, 列标签] = 新值\ndf.iloc[行位置, 列位置] = 新值\n```\n\n**参数:**\n- `loc`: 基于标签（行名和列名）\n- `iloc`: 基于位置（整数索引）\n\n**特点:**\n- ✅ 精确控制修改位置\n- ✅ 支持切片和条件\n- ✅ 避免链式赋值警告\n\n**适用场景:** 修改特定位置的数据"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 示例1: 创建示例数据"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "df = pd.DataFrame({\n    '姓名': ['Alice', 'Bob', 'Charlie'],\n    '分数': [85, 90, 78],\n    '等级': ['B', 'A', 'C']\n}, index=['row1', 'row2', 'row3'])\n\nprint(\"原始 DataFrame:\")\nprint(df)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 示例2: 使用 loc 修改单个值\n\n修改 row1 行的分数。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "df_copy = df.copy()\ndf_copy.loc['row1', '分数'] = 95\nprint(\"修改单个值:\")\nprint(df_copy)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 示例3: 使用 loc 修改整行\n\n替换 row2 的所有值。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "df_copy = df.copy()\ndf_copy.loc['row2', :] = ['David', 100, 'A+']\nprint(\"修改整行:\")\nprint(df_copy)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 示例4: 使用 loc 修改多行多列\n\n同时修改多个位置的值。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "df_copy = df.copy()\ndf_copy.loc[['row1', 'row3'], ['分数', '等级']] = [[88, 'B+'], [82, 'B']]\nprint(\"修改多行多列:\")\nprint(df_copy)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 示例5: 使用 iloc 修改（基于位置）\n\n修改第一行第二列的值。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "df_copy = df.copy()\ndf_copy.iloc[0, 1] = 92\nprint(\"使用 iloc 修改:\")\nprint(df_copy)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 示例6: 使用 iloc 修改切片范围\n\n修改前两行的分数列。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "df_copy = df.copy()\ndf_copy.iloc[0:2, 1] = [95, 98]\nprint(\"修改切片:\")\nprint(df_copy)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 3. 使用 at 和 iat 修改单个值\n\n### 方法说明\n\n`at` 和 `iat` 专门用于修改单个值，性能更好。\n\n**语法:**\n```python\ndf.at[行标签, 列标签] = 新值\ndf.iat[行位置, 列位置] = 新值\n```\n\n**特点:**\n- ✅ 性能最快\n- ✅ 只能修改单个值\n- ✅ 直接修改原 DataFrame\n\n**适用场景:** 修改单个单元格时使用，性能优于 loc/iloc"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 示例1: 创建示例数据"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "df = pd.DataFrame({\n    'A': [1, 2, 3],\n    'B': [4, 5, 6]\n}, index=['x', 'y', 'z'])\n\nprint(\"原始 DataFrame:\")\nprint(df)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 示例2: 使用 at 修改（基于标签）\n\n修改 x 行 A 列的值。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "df_copy = df.copy()\ndf_copy.at['x', 'A'] = 100\nprint(\"使用 at 修改:\")\nprint(df_copy)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 示例3: 使用 iat 修改（基于位置）\n\n修改第一行第一列的值。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "df_copy = df.copy()\ndf_copy.iat[0, 0] = 200\nprint(\"使用 iat 修改:\")\nprint(df_copy)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 4. 使用 replace() 替换值\n\n### 方法说明\n\n`replace()` 用于替换 DataFrame 中的特定值。\n\n**语法:**\n```python\ndf.replace(to_replace, value)\ndf.replace({旧值: 新值, ...})\n```\n\n**参数:**\n- `to_replace`: 要替换的值\n- `value`: 新值\n- `regex`: 是否使用正则表达式\n\n**特点:**\n- ✅ 可以批量替换\n- ✅ 支持正则表达式\n- ✅ 支持字典映射\n- ✅ 默认返回新 DataFrame\n\n**适用场景:** 批量替换特定值"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 示例1: 创建示例数据"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "df = pd.DataFrame({\n    '姓名': ['张三', '李四', '王五'],\n    '性别': ['男', '女', '男'],\n    '分数': [85, 90, -1]\n})\n\nprint(\"原始 DataFrame:\")\nprint(df)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 示例2: 替换单个值\n\n将 -1 替换为 NaN。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "df_replaced = df.replace(-1, np.nan)\nprint(\"替换 -1 为 NaN:\")\nprint(df_replaced)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 示例3: 使用字典替换\n\n将性别的中文替换为英文缩写。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "df_replaced = df.replace({'男': 'M', '女': 'F'})\nprint(\"替换性别:\")\nprint(df_replaced)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 示例4: 针对特定列替换\n\n只在性别列进行替换。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "df_replaced = df.replace({'性别': {'男': 'Male', '女': 'Female'}})\nprint(\"针对性别列替换:\")\nprint(df_replaced)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 示例5: 使用正则表达式替换\n\n去除文本中的数字。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "df_text = pd.DataFrame({\n    '文本': ['hello123', 'world456', 'test789']\n})\n\ndf_replaced = df_text.replace(r'\\d+', '', regex=True)\nprint(\"去除数字:\")\nprint(df_replaced)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 5. 使用 apply() 和 map() 修改\n\n### 方法说明\n\n`apply()` 和 `map()` 用于应用函数进行数据转换。\n\n**语法:**\n```python\ndf['列'].apply(函数)\ndf['列'].map(字典或函数)\n```\n\n**区别:**\n- `apply()`: 更通用，可用于 Series 和 DataFrame\n- `map()`: 只用于 Series，支持字典映射\n\n**特点:**\n- ✅ 支持自定义函数\n- ✅ 支持 lambda 表达式\n- ❌ 性能相对较慢\n\n**适用场景:** 需要复杂转换逻辑时"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 示例1: 创建示例数据"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "df = pd.DataFrame({\n    '姓名': ['alice', 'bob', 'charlie'],\n    '分数': [85, 90, 78]\n})\n\nprint(\"原始 DataFrame:\")\nprint(df)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 示例2: 使用 apply() 应用函数\n\n将姓名转换为大写。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "df_copy = df.copy()\ndf_copy['姓名'] = df_copy['姓名'].apply(str.upper)\nprint(\"姓名转大写:\")\nprint(df_copy)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 示例3: 使用 apply() 和 lambda\n\n分数提高 10%。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "df_copy = df.copy()\ndf_copy['分数'] = df_copy['分数'].apply(lambda x: x * 1.1)\nprint(\"分数提高10%:\")\nprint(df_copy)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 示例4: 使用 map() 映射值\n\n根据分数映射等级。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "grade_map = {85: 'B', 90: 'A', 78: 'C'}\ndf_copy = df.copy()\ndf_copy['等级'] = df_copy['分数'].map(grade_map)\nprint(\"添加等级列:\")\nprint(df_copy)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 示例5: 对整个 DataFrame 应用函数\n\n所有数值列翻倍。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "df_numeric = pd.DataFrame({\n    'A': [1, 2, 3],\n    'B': [4, 5, 6]\n})\n\ndf_doubled = df_numeric.apply(lambda x: x * 2)\nprint(\"所有值翻倍:\")\nprint(df_doubled)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 6. 使用 where() 和 mask() 条件修改\n\n### 方法说明\n\n`where()` 和 `mask()` 用于条件替换。\n\n**语法:**\n```python\ndf.where(条件, 替换值)  # 保留满足条件的，其他替换\ndf.mask(条件, 替换值)   # 替换满足条件的，其他保留\n```\n\n**区别:**\n- `where()`: 保留 True 的值，False 的替换\n- `mask()`: 替换 True 的值，False 的保留\n\n**特点:**\n- ✅ 高效的条件替换\n- ✅ 向量化操作\n- ✅ 返回新 DataFrame\n\n**适用场景:** 基于条件批量替换值"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 示例1: 创建示例数据"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "df = pd.DataFrame({\n    '分数': [85, 90, 78, 92, 65]\n})\n\nprint(\"原始 DataFrame:\")\nprint(df)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 示例2: 使用 where()\n\n保留分数 >= 80 的值，其他改为 0。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "df_where = df['分数'].where(df['分数'] >= 80, 0)\nprint(\"where() - 分数<80的改为0:\")\nprint(df_where)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 示例3: 使用 mask()\n\n将分数 < 80 的值改为 0。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "df_mask = df['分数'].mask(df['分数'] < 80, 0)\nprint(\"mask() - 分数<80的改为0:\")\nprint(df_mask)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 示例4: 使用 np.where 进行条件替换\n\n`np.where()` 是另一个常用的条件替换方法。\n\n**语法:**\n```python\nnp.where(条件, 真值, 假值)\n```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "df_copy = df.copy()\ndf_copy['等级'] = np.where(df_copy['分数'] >= 90, 'A', \n                          np.where(df_copy['分数'] >= 80, 'B', 'C'))\nprint(\"使用 np.where 添加等级:\")\nprint(df_copy)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 7. 批量修改和转换\n\n常见的批量修改操作。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 示例1: 数据类型转换\n\n使用 `astype()` 转换数据类型。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "df = pd.DataFrame({\n    '年龄': ['25', '30', '35'],\n    '工资': ['8000', '12000', '15000']\n})\n\nprint(\"原始数据类型:\")\nprint(df.dtypes)\n\n# 转换为数值类型\ndf_converted = df.astype({'年龄': int, '工资': int})\nprint(\"\\n转换后数据类型:\")\nprint(df_converted.dtypes)\nprint(\"\\nDataFrame:\")\nprint(df_converted)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 示例2: 填充缺失值\n\n使用 `fillna()` 填充缺失值。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "df = pd.DataFrame({\n    'A': [1, np.nan, 3],\n    'B': [4, 5, np.nan],\n    'C': [7, 8, 9]\n})\n\nprint(\"原始 DataFrame:\")\nprint(df)\n\n# 填充为0\ndf_filled = df.fillna(0)\nprint(\"\\n填充为0:\")\nprint(df_filled)\n\n# 填充为均值\ndf_filled = df.fillna(df.mean())\nprint(\"\\n填充为均值:\")\nprint(df_filled)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 示例3: 字符串批量操作\n\n使用 `str` 访问器进行字符串操作。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "df = pd.DataFrame({\n    '姓名': ['  Alice  ', 'BOB', 'charlie']\n})\n\nprint(\"原始 DataFrame:\")\nprint(df)\n\n# 批量字符串处理\ndf['姓名'] = df['姓名'].str.strip().str.lower().str.capitalize()\nprint(\"\\n处理后:\")\nprint(df)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 示例4: 数值运算\n\n基于现有列进行计算。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "df = pd.DataFrame({\n    '价格': [100, 200, 300],\n    '数量': [2, 3, 1]\n})\n\n# 添加计算列\ndf['总价'] = df['价格'] * df['数量']\ndf['折扣价'] = df['价格'] * 0.9\n\nprint(\"添加计算列:\")\nprint(df)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 总结\n\n### 修改数据的方法对比\n\n| 方法 | 适用场景 | 性能 | 修改原数据 |\n|------|---------|------|-----------|\n| 直接赋值 | 修改整列 | 快 | 是 |\n| `loc/iloc` | 条件修改、切片修改 | 中等 | 是 |\n| `at/iat` | 修改单个值 | 最快 | 是 |\n| `replace()` | 值替换 | 中等 | 否 |\n| `apply()` | 复杂转换 | 慢 | 否 |\n| `map()` | 值映射 | 中等 | 否 |\n| `where()/mask()` | 条件替换 | 快 | 否 |\n\n### 关键要点\n\n1. **优先使用向量化操作**，避免循环\n2. **使用 `loc/iloc`** 进行条件修改，避免链式赋值\n3. **修改单个值时使用 `at/iat`**，性能更好\n4. **使用 `copy()`** 创建副本，避免意外修改原数据\n5. **`replace()`** 适合简单值替换\n6. **`apply()`** 适合复杂转换，但性能较慢\n7. **`where()/mask()`** 适合条件替换\n8. **向量化操作** > apply() > 循环\n\n### 性能建议\n\n- 向量化操作（直接赋值、where/mask）最快\n- at/iat 比 loc/iloc 快（单值修改）\n- 尽量使用内置方法而非自定义函数\n- 避免在循环中修改 DataFrame"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "name": "python",
   "version": "3.8.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}